import 'dart:async';
import 'dart:io';

import 'package:amap_flutter_location/amap_flutter_location.dart';
import 'package:amap_flutter_location/amap_location_option.dart';

import '../config/map_config.config.dart';
import './app_permission_service.service.dart';

typedef LocationChanged = void Function(double? latitude, double? longitude);

/// Provides map location service and notifies caller once location changed.
///
/// [onceLocation] means if only tracking location once. Default value is true. [locationChanged] will only be fired once.
/// When [onceLocation] is false [locationChanged] will be fired continuously when location changes each time.
class MapLocationService {
  MapLocationService(this.locationChanged, {this.onceLocation = true}) {
    AMapFlutterLocation.setApiKey(MapConfig.androidKey, '');

    // https://lbs.amap.com/news/sdkhgsy
    // 因为高德地图隐私政策更改，必须在使用定位前调用。
    AMapFlutterLocation.updatePrivacyShow(true, true);
    AMapFlutterLocation.updatePrivacyAgree(true);

    _onLcationChanged();
  }

  final LocationChanged? locationChanged;
  final bool onceLocation;

  // For map location.
  final AMapFlutterLocation _location = AMapFlutterLocation();

  // Listens on location change.
  late StreamSubscription<Map<String, Object>> _locationListener;

  void dispose() {
    // Removes location listener.
    // if (_locationListener != null) {
    _locationListener.cancel();
    // }

    // Destories location.
    _location.stopLocation();
    _location.destroy();
  }

  /// Starts locating user current position.
  Future<void> startLocation() async {
    if (await _requestPermissions()) {
      _location.setLocationOption(AMapLocationOption(
        onceLocation: onceLocation,
        locationMode: AMapLocationMode.Hight_Accuracy,
        desiredAccuracy: DesiredAccuracy.Best,
      ));

      _location.startLocation();
    }
  }

  /// Checks on device location permission.
  Future<bool> _requestPermissions() async {
    if (Platform.isIOS) {
      _location.getSystemAccuracyAuthorization();
    }

    return AppPermissionService.requestLocationWhenInUsePermissions();
  }

  /// Listens on location change event and fires callback.
  void _onLcationChanged() {
    _locationListener = _location.onLocationChanged().listen((result) {
      // ios result['latitude'] 和 result['latitude'] 是字符串类型
      final latitude = result['latitude'] != null
          ? double.parse(result['latitude'].toString())
          : null;

      final longitude = result['longitude'] != null
          ? double.parse(result['longitude'].toString())
          : null;

      locationChanged?.call(latitude, longitude);
    });
  }
}
